<?php

namespace Viettrans\FrontBundle\Services;

use Doctrine\ORM\EntityManager;

class MyCacheManager {
    private $cachePath;
    private $em;
    
    /**
     * The constructor
     * 
     * @param EntityManager $em EntityManager added by Dependency Injection
     */
    public function __construct(EntityManager $em) {
        $this->cachePath = realpath(dirname(__FILE__).'/../Cache');
        $this->em = $em;
    }
    
    /**
     * Get cached categories, if cache does not exist yet then generate the cache
     * 
     * @param array $options It's not yet used for this moment
     * @return array The cached categories 
     */
    public function getCategories() {
        $filePath = $this->cachePath.'/CategoriesCached.php';
        
        # Check if categories are not cached then generate the categories's cache
        if (!file_exists($filePath)) {
             $_categoriesCached = array();
            
             $query = $this->em->createQuery('SELECT c FROM ViettransFrontBundle:Category c WHERE c.parentId = 0');
    
             $parents = $query->getResult();
             foreach ($parents as $parent) {
                 $parentId = $parent->getId();
                 $query2 = $this->em->createQuery('SELECT c FROM ViettransFrontBundle:Category c WHERE c.parentId = :parentId')
                                 ->setParameter('parentId', $parentId);
                 
                 $childs = $query2->getArrayResult();
                 
                 $_categoriesCached[] = array(
                     'id'     => $parent->getId(),
                     'name'   => $parent->getName(),
                     'childs' => $childs,
                 );
             }

             file_put_contents($filePath, "<?php\n \$_categoriesCached = ".var_export($_categoriesCached, true).";");
        
        } else {
            require_once $filePath;
        }

        return $_categoriesCached;
    }
    
    
    /**
     * Get cached types, if cache does not exist yet then generate the cache
     * 
     * @return array The cached types
     */
    public function getTypes() {
        $filePath = $this->cachePath.'/TypesCached.php';
        
        # Check if categories are not cached then generate the categories's cache
        if (!file_exists($filePath)) {
             $query =  $this->em->createQuery('
                SELECT t
                FROM ViettransFrontBundle:Type as t
            ');
             
             $_typesCached = $query->getArrayResult();
             
             file_put_contents($filePath, "<?php\n \$_typesCached = ".var_export($_typesCached, true).";");
        } else {
            require_once $filePath;
        }

        return $_typesCached;
    }
    
    /**
     * Get the cached localities, if input < 5 and cache exists then return the cache
     * else if input < 5 and cache does not exist then generate the cache then return the cache
     * else if input > 5 or cache does not exist then request directly to the data base
     * 
     * @param array $options
     * @return array Cached localities 
     */
    public function getLocalities($options = array()) {
        $input = $options['input'];
        
        $filePath = $this->cachePath.'/Localities/'.$input.'.json';
    
        # If cache exists then return the cache content
        if (strlen($input) < 5 && file_exists($filePath)) {
            return file_get_contents($filePath);
        
        # If cache does not exist then generate the cache and return the cache content
        } else {
            $data = array(
                'query'       => $input,
                'suggestions' => $this->em->getRepository('ViettransFrontBundle:Town')->getLocalities($options),
            );
            
            # Generate cache
            if (strlen($input) < 5) {
                file_put_contents($filePath, json_encode($data));
            }
            
            return json_encode($data);
        }
    }
    
    /**
     * This function will take the array options then serializes it and concatenate with date('Ymd')
     * for build the cacheId. When a request is demanded, the system will build the cacheId then verity if
     * the cached exists or not, if the cache exist then return it else then generate it by call the 
     * countAnnouncements function of AnnouncementRepository.
     * The system then verify the cache, if it exists since more than 2 hours then delete it then regenerate
     * 
     * @param array $options
     * @return int 
     */
    public function countAnnouncements($options = array()) {
        $cacheId = date('Ymd').'-'.md5(serialize($options));
        $filePath = $this->cachePath.'/CountAnnouncements/'.$cacheId.'.php';

        if (file_exists($filePath)) {
            require_once $filePath;
        } else {
           $announcementRepo = $this->em->getRepository('ViettransFrontBundle:Announcement');
           $_countAnnouncementCached = $announcementRepo->countAnnouncements($options);
           
           # Generate the cache
           file_put_contents($filePath, "<?php\n \$_countAnnouncementCached = ".$_countAnnouncementCached.";");
        }
        
        return $_countAnnouncementCached;
    }
}
